package com.qf.openapi.web.master.service.impl;

import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.druid.sql.PagerUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.qf.openapi.web.master.dao.UserDao;
import com.qf.openapi.web.master.entity.User;
import com.qf.openapi.web.master.service.UserService;
import com.qf.openapi.web.master.utils.Contants;
import com.qf.openapi.web.master.utils.QfFileAppender;
import com.qf.openapi.web.master.vo.InUserVo;
import com.qf.openapi.web.master.vo.ResultVo;
import com.qf.openapi.web.master.vo.TableVo;
import com.qf.openapi.web.master.vo.UserVo;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Value("{file.updload.dir}")
    private String uploaddir;

    @Autowired
    private UserDao userDao;

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public User getUser(Integer id) {
        return userDao.getUserById(id);
    }


    @Override
    public User login(String username, String password) {
        log.debug("userservice接收页面的用户名是username={},password={}", username, password);
        User user = userDao.selectNameAndPassword(username, password);

        return user;

    }

    @Override
    public Integer addUser(User user) {
       return  userDao.insertUser(user);
    }

    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultVo regist(UserVo userVo, String realPath , HttpSession session) {
        log.debug("保存头像文件:");
        //1.保存头像文件
        //获取原文件名称
        String originalFilename = userVo.getPhotopath().getOriginalFilename();
        //获取后缀
        String extension = FilenameUtils.getExtension(originalFilename);
        ServletContext context = session.getServletContext();

        realPath= context.getRealPath("/file");
        // 判断upload目录是否已经存在，如果不存在，则创建
        final File dir = new File(realPath);
        if (!dir.exists()) {
            dir.mkdirs();
        }

        //随机生成文件名
        String randomName = UUID.randomUUID().toString();

        //最后文件名
        String finalFileName = randomName + "." + extension;

        //拼装最后的文件路径
        final String finalFilePath = realPath + File.separator +finalFileName;
        log.debug("用户头像存放的路径为{}", finalFilePath);

        //上传
        userVo.getPhotopath().transferTo(new File(finalFilePath));

        log.debug("保存文件成功到 finalpath={}" ,finalFilePath);

        log.debug("保存用户的注册信息到数据库");

        //UserVo  --- 》user
        User user = new User();
        //从一个对象中拷贝相同属性到另一个对象
        BeanUtils.copyProperties(userVo,user);

        //补全余下属性
        user.setName(userVo.getUsername());
        user.setRegistTime(new Date());
        user.setPhotopath(finalFileName);

        //处理密码加密
        String md5password = DigestUtil.md5Hex(userVo.getPassword());
        user.setPassword(md5password);

        log.debug("保存的用户信息为：user={}",user);
        userDao.insertUser(user);
        return new ResultVo(Contants.SUCCESS_CODE,"注册成功");



    }

    @Override
    public User getUserss(String username, String password) {
        log.debug("userservice接收页面的用户名是username={},password={}", username, password);
        //密码加密处理
        String md5password = DigestUtil.md5Hex(password);
        User user = userDao.selectNameAndPassword(username, md5password);
        return user;
    }

    @Override
    public User getUserByName(String name) {
        User user = userDao.selectUserName(name);
        return user;
    }


    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public ResultVo checkUserNmae(String username) {

        User user = userDao.getUserByName(username);
        if (user ==null){
            //用户名不存在
            return new ResultVo(Contants.FAIL_CODE,"用户名不存在");
        }else {
            return new ResultVo(Contants.SUCCESS_CODE,"用户名存在");
        }
    }

    /**
     *
     * @param page 页号
     * @param limit 页大小
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public TableVo getAllUserByPage(Integer page, Integer limit) {

        //查询user总条数
        Integer count = userDao.selectCount();

        //查询当前页的用户数据

        int start = (page - 1) * limit;

        List<User> users = userDao.selectUserByPage(start,limit);

        TableVo<User> userTableVo = new TableVo<>();
        userTableVo.setCode(0);
        userTableVo.setMsg("ok");
        userTableVo.setData(users);
        userTableVo.setCount(count);
        return userTableVo;
    }

    @Override
    public TableVo getAll(Integer page, Integer limit) {

        Integer integer = userDao.selectCount();


        PageHelper.startPage(page,limit);
        List<User> allUser = userDao.getAllUser();

        TableVo tableVo=new TableVo(0,"查询成功",integer,allUser);
        return tableVo;
    }

    /**
     *
     * @param username
     * @param md5password
     * @return
     */
    @Override
    public User restoreUser(String username, String md5password) {
        User user = userDao.selectNameAndPassword(username, md5password);
        return user;
    }

    @Override
    public Integer delUser(Integer[] ids) {

        Integer user = userDao.delUssers(ids);

        return user;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer InserInUsers(InUserVo users) {

        User user1= new User(users.getUsername(),users.getSex(),users.getBirthday(),new Date());

        String pwd = DigestUtil.md5Hex(users.getPassword());
        user1.setPassword(pwd);
        Integer integer = userDao.insertUser(user1);
        return integer;

    }

//    @Override
//    public ResultVo delteUsers(List<Integer> ids) {
//        return null;
//    }

    @Override
    public ResultVo updateUser(User user) {

        log.debug("接收到参数user={}",user);
        ///密码处理
        String password = user.getPassword();

        //查询原来数据库中用户信息
        User dbUser = userDao.getUserById(user.getId());
        String dbpassword = dbUser.getPassword();
        if (!password.equals(dbpassword)){
            log.debug("用户修改了密码，重新md5");
            String md5pwd = DigestUtil.md5Hex(password);
            user.setPassword(md5pwd);
        }

        userDao.updateUser(user);
            return new ResultVo(Contants.SUCCESS_CODE,"修改成功");
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public TableVo<User> getUserByCondition(Integer page, Integer limit, UserVo userVo) {
        log.debug("page={},limit={},uservo={}",page,limit,userVo);
        PageHelper.startPage(page,limit);
        List<User> data = userDao.getUserByCondition(userVo);
        PageInfo<User> pageInfo = new PageInfo<>(data);
        long total = pageInfo.getTotal();
        return TableVo.ok((int)total,data);
    }

    /**
     * 全量导出user表数据
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public String export() throws IOException {
        //1.查询所有用户数据
        List<User> allUser = userDao.getAllUser();

        //2.List<User>---》List<String>

        List<String> list = allUser.stream(). //list=>stream
                map(user -> user.toCsvString()). //stream api 调用
                collect(Collectors.toList()); //stream==》list


        //3.list<String > --> user.csv

        //每次导出的文件生成一个唯一的文件名，避免多用户同时下载时写同一个文件
        String filename = UUID.randomUUID().toString()+".csv";
        String finalPath =  uploaddir+File.separator + filename;
        QfFileAppender qfFileAppender = new QfFileAppender(finalPath);

        qfFileAppender.appendListToFile(list);

        qfFileAppender.close();

        return null;
    }


}
